################################################################################################################################################
####### Everything in Moderation? The Effect of Extremist Nominations on Individual and Corporate PAC Fundraising
####### Author: Mellissa Meisels (mellissa.meisels@yale.edu)
################################################################################################################################################
library(plyr)
library(tidyverse)
library(formattable)
library(kableExtra)
library(cowplot)
library(rdd)
library(rdrobust)
library(fixest)
library(modelsummary)

options(modelsummary_factory_latex = 'kableExtra')
options(scipen=999)

###################################################
# Uncomment to set wd to location of replication files
###################################################
#setwd("~/Yale University Dropbox/Mellissa Meisels/Projects/Extremist Contributions/PSRM final/")

###################################################
# Table 1
###################################################
# Reading in relevant datasets
tab1_all <- readRDS("Tab1_all.rds")
tab1_opposed <- readRDS("Tab1_opposed.rds")
tab1_different <- readRDS("Tab1_different.rds")
tab1_close <- readRDS("Tab1_close.rds")

# Functions to compute summary statistics
fun_stats <- function(x) c(mean(ifelse(x$party=="D", 1, 0)), # Democratic primaries
                           mean(ifelse(x$prim_type=="O", 1, 0)), # Open seat primaries
                           mean(abs(x$dem_pres_vs-.5)), # Mean district Democratic vote share above 50-50 
                           median(abs(x$dem_pres_vs-.5)), # Median district Democratic vote share above 50-50 
                           mean(x$midterm), # Primaries occurring in midterm years
                           mean(ifelse(x$year<1990, 1, 0)), # Primaries occurring in the 1980s
                           mean(ifelse(x$year>=1990 & x$year<2000, 1, 0)), # Primaries occurring in the 1990s
                           mean(ifelse(x$year>=2000 & x$year<2010, 1, 0)), # Primaries occurring in the 2000s
                           mean(ifelse(x$year>=2010, 1, 0))) # Primaries occurring in the 2010s and 2020

fun_n <- function(x) format(nrow(x), big.mark=",") # Total number of primaries

# Assembling table 
tab1 <- data.frame("Variable" = c("Democratic", "Open Seat", "Mean Pres VS Margin", "Median Pres VS Margin",
                                             "Midterm", "1980 -- 1988", "1990 -- 1998", "2000 -- 2008", "2010 -- 2020"),
                              "All" = fun_stats(tab1_all), "Opposed" = fun_stats(tab1_opposed),
                              "Extreme.v.Moderate" = fun_stats(tab1_different), "Close.Primary" = fun_stats(tab1_close)) %>%
  mutate_if(is.numeric, ~paste0(format(round(. * 100, digits=2), nsmall=2), "%")) %>%
  add_row("Variable" = "N", "All" = fun_n(tab1_all), "Opposed" = fun_n(tab1_opposed), 
          "Extreme.v.Moderate" = fun_n(tab1_different), "Close.Primary" = fun_n(tab1_close))

tab1 <- kable(tab1, format = "latex") %>% kable_styling(font_size = 10)

save_kable(tab1, "tab1.tex")

###################################################
# Figure 1
###################################################
# Reading in primary dataset
top_quartile_primaries <- readRDS("Top_Quartile_Primaries.rds")

# Calculating contribution averages
mean.ind.safe <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==0) %>% 
  group_by(ext_win) %>% summarize(mean=mean(log(winner_gen_indiv_amt+1), na.rm=T))

mean.pac.safe <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==0) %>% 
  group_by(ext_win) %>% summarize(mean=mean(log(winner_gen_corp_amt+1), na.rm=T))

mean.ind.comp <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==1) %>% 
  group_by(ext_win) %>% summarize(mean=mean(log(winner_gen_indiv_amt+1), na.rm=T))

mean.pac.comp <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==1) %>% 
  group_by(ext_win) %>% summarize(mean=mean(log(winner_gen_corp_amt+1), na.rm=T))

# Contribution density plots
ind.safe.plot <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==0) %>% 
  ggplot(aes(x=log(winner_gen_indiv_amt+1), color = ext_win)) + geom_density(size=1) + theme_light() + 
  geom_vline(data = mean.ind.safe, aes(xintercept = mean, color = ext_win), linetype="dashed") + xlim(0,15) + ylim(0,.4) +
  theme(plot.title = element_text(face="bold", size = 12),
        legend.justification=c(0,1), legend.position=c(.01,.99),
        legend.text = element_text(size = 10)) + 
  scale_color_grey(name = element_blank(), labels = c("Moderate","Extreme")) +
  labs(y="", x = "log(General Election Contributions + 1)", title = "Individual Contributions,\nOutside 20% Bandwidth")

pac.safe.plot <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==0) %>% 
  ggplot(aes(x=log(winner_gen_corp_amt+1), color = ext_win)) + geom_density(size=1) + theme_light() + 
  geom_vline(data = mean.pac.safe, aes(xintercept = mean, color = ext_win),
             linetype="dashed") + xlim(0,15) + ylim(0,.4) +
  theme(plot.title = element_text(face="bold", size = 12),
        legend.justification=c(0,1), legend.position=c(.01,.99),
        legend.text = element_text(size = 10)) + 
  scale_color_grey(name = element_blank(), labels = c("Moderate","Extreme")) +
  labs(y="", x = "log(General Election Contributions + 1)", title = "Corporate PAC Contributions,\nOutside 20% Bandwidth")

ind.comp.plot <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==1) %>% 
  ggplot(aes(x=log(winner_gen_indiv_amt+1), color = ext_win)) + geom_density(size=1) + theme_light() + 
  geom_vline(data = mean.ind.comp, aes(xintercept = mean, color = ext_win),
             linetype="dashed") + xlim(0,15) + ylim(0,.4) +
  theme(plot.title = element_text(face="bold", size = 12),
        legend.justification=c(0,1), legend.position=c(.01,.99),
        legend.text = element_text(size = 10)) + 
  scale_color_grey(name = element_blank(), labels = c("Moderate","Extreme")) +
  labs(y="", x = "log(General Election Contributions + 1)", title = "Individual Contributions,\nWithin 20% Bandwidth")

pac.comp.plot <- top_quartile_primaries %>% mutate(ext_win = as.factor(ext_win)) %>% filter(competitive==1) %>% 
  ggplot(aes(x=log(winner_gen_corp_amt+1), color = ext_win)) + geom_density(size=1) + theme_light() + 
  geom_vline(data = mean.pac.comp, aes(xintercept = mean, color = ext_win),
             linetype="dashed") + xlim(0,15) + ylim(0,.4) +
  theme(plot.title = element_text(face="bold", size = 12),
        legend.justification=c(0,1), legend.position=c(.01,.99),
        legend.text = element_text(size = 10)) + 
  scale_color_grey(name = element_blank(), labels = c("Moderate","Extreme")) +
  labs(y="", x = "log(General Election Contributions + 1)", title = "Corporate PAC Contributions,\nWithin 20% Bandwidth")

# Plotting altogether
pdf(file = "Figure1.pdf")

plot_grid(ind.safe.plot, pac.safe.plot, ind.comp.plot, pac.comp.plot, nrow = 2)

dev.off()

###################################################
# Figure 2
###################################################
# Individual contribution plot
pdf(file = "Fig2A.pdf", width = 5, height = 4)

ggplot(top_quartile_primaries, aes(x = ext_vshare, y = log(winner_gen_indiv_amt+1))) +
  theme_bw() + theme(plot.title = element_text(face="bold", size = 12, hjust = .5), axis.text = element_text(color = "black")) +
  geom_point(size = 0.5, alpha = 0.2) + 
  geom_smooth(data = filter(top_quartile_primaries, ext_vshare > 0), color = "black") +
  geom_smooth(data = filter(top_quartile_primaries, ext_vshare < 0), color = "black") +
  geom_vline(xintercept = 0) + ylim(0, 15) + scale_x_continuous(labels=scales::percent) +
  labs(title = "log(Individual Contributions + 1)", x = "Extremist Vote Margin", y = NULL) +
  annotate("text", y = 3, x = -.25, label = "Moderate Nominee", color="black") +
  annotate("text", y = 3, x = .25, label = "Extreme Nominee", color="black")

dev.off()

# Corporate contribution plot
pdf(file = "Fig2B.pdf", width = 5, height = 4)

ggplot(top_quartile_primaries, aes(x = ext_vshare, y = log(winner_gen_corp_amt+1))) +
  theme_bw() + theme(plot.title = element_text(face="bold", size = 12, hjust = .5), axis.text = element_text(color = "black")) +
  geom_point(size = 0.5, alpha = 0.2) + 
  geom_smooth(data = filter(top_quartile_primaries, ext_vshare > 0), color = "black") +
  geom_smooth(data = filter(top_quartile_primaries, ext_vshare < 0), color = "black") +
  geom_vline(xintercept = 0) + ylim(0, 15) + scale_x_continuous(labels=scales::percent) +
  labs(title = "log(Corporate PAC Contributions + 1)", x = "Extremist Vote Margin", y = NULL) +
  annotate("text", y = 3, x = -.25, label = "Moderate Nominee", color="black") +
  annotate("text", y = 3, x = .25, label = "Extreme Nominee", color="black")

dev.off()

###################################################
# Table 2
###################################################
# Reading in top median primary data
top_median_primaries <- readRDS("Top_Median_Primaries.rds")

# Calculating IK and CCT bandwidths for top quartile models
ik.ind.quartile <- IKbandwidth(top_quartile_primaries$ext_vshare, log(top_quartile_primaries$winner_gen_indiv_amt+1), kernel = "triangular", cutpoint = 0)
ik.corp.quartile <- IKbandwidth(top_quartile_primaries$ext_vshare, log(top_quartile_primaries$winner_gen_corp_amt+1), kernel = "triangular", cutpoint = 0)
cct.ind.quartile <- rdbwselect(log(top_quartile_primaries$winner_gen_indiv_amt+1), top_quartile_primaries$ext_vshare, kernel = "triangular")$bws[1]
cct.corp.quartile <- rdbwselect(log(top_quartile_primaries$winner_gen_corp_amt+1), top_quartile_primaries$ext_vshare, kernel = "triangular")$bws[1]

# Calculating IK and CCT bandwidths for top median models
ik.ind.median <- IKbandwidth(top_median_primaries$ext_vshare, log(top_median_primaries$winner_gen_indiv_amt+1), kernel = "triangular", cutpoint = 0)
ik.corp.median <- IKbandwidth(top_median_primaries$ext_vshare, log(top_median_primaries$winner_gen_corp_amt+1), kernel = "triangular", cutpoint = 0)
cct.ind.median <- rdbwselect(log(top_median_primaries$winner_gen_indiv_amt+1), top_median_primaries$ext_vshare, kernel = "triangular")$bws[1]
cct.corp.median <- rdbwselect(log(top_median_primaries$winner_gen_corp_amt+1), top_median_primaries$ext_vshare, kernel = "triangular")$bws[1]

# Calculate kernel weights
top_quartile_primaries <- top_quartile_primaries %>% 
  mutate(ik.wgt.ind = kernelwts(top_quartile_primaries$ext_vshare, center = 0, bw = ik.ind.quartile),
         ik.wgt.corp = kernelwts(top_quartile_primaries$ext_vshare, center = 0, bw = ik.corp.quartile),
         cct.wgt.ind = kernelwts(top_quartile_primaries$ext_vshare, center = 0, bw = cct.ind.quartile),
         cct.wgt.corp = kernelwts(top_quartile_primaries$ext_vshare, center = 0, bw = cct.corp.quartile))

top_median_primaries <- top_median_primaries %>% 
  mutate(ik.wgt.ind = kernelwts(top_median_primaries$ext_vshare, center = 0, bw = ik.ind.median),
         ik.wgt.corp = kernelwts(top_median_primaries$ext_vshare, center = 0, bw = ik.corp.median),
         cct.wgt.ind = kernelwts(top_median_primaries$ext_vshare, center = 0, bw = cct.ind.median),
         cct.wgt.corp = kernelwts(top_median_primaries$ext_vshare, center = 0, bw = cct.corp.median))

# Run poisson regression models
pois_ind_quart_ik <- feglm(winner_gen_indiv_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                         top_quartile_primaries, subset = ~winner_gen_indiv_amt>=0, weights = ~ik.wgt.ind, cluster = "winner_DIME_ID")

pois_ind_quart_cct <- feglm(winner_gen_indiv_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                           top_quartile_primaries, subset = ~winner_gen_indiv_amt>=0, weights = ~cct.wgt.ind, cluster = "winner_DIME_ID")

pois_corp_quart_ik <- feglm(winner_gen_corp_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                                top_quartile_primaries, subset = ~winner_gen_corp_amt>=0, weights = ~ik.wgt.corp, cluster = "winner_DIME_ID")

pois_corp_quart_cct <- feglm(winner_gen_corp_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                                 top_quartile_primaries, subset = ~winner_gen_corp_amt>=0, weights = ~cct.wgt.corp, cluster = "winner_DIME_ID")

pois_ind_med_ik <- feglm(winner_gen_indiv_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                         top_median_primaries, subset = ~winner_gen_indiv_amt>=0, weights = ~ik.wgt.ind, cluster = "winner_DIME_ID")

pois_ind_med_cct <- feglm(winner_gen_indiv_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                        top_median_primaries, subset = ~winner_gen_indiv_amt>=0, weights = ~cct.wgt.ind, cluster = "winner_DIME_ID")

pois_corp_med_ik <- feglm(winner_gen_corp_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                        top_median_primaries, subset = ~winner_gen_corp_amt>=0, weights = ~ik.wgt.corp, cluster = "winner_DIME_ID")

pois_corp_med_cct <- feglm(winner_gen_corp_amt ~ ext_win * ext_vshare | factor(year), family = "quasipoisson",
                         top_median_primaries, subset = ~winner_gen_corp_amt>=0, weights = ~cct.wgt.corp, cluster = "winner_DIME_ID")

# Build results table
fmt_r4 <- function(x) format(round(x, digits=4), nsmall=4)
fmt_n <- function(x) format(round(x, digits=0), big.mark=",")

gm <- list(list("raw" = "nobs", "clean" = "Observations", "fmt" = fmt_n),
           list("raw" = "r.squared", "clean" = "R-Squared", "fmt" = fmt_r4))

tab2_FEs <- data.frame("Coefficients" = c("Year FE", "Bandwidth"),
                            "Model 1" = c("\\checkmark", "IK"),
                            "Model 2" = c("\\checkmark", "CCT"),
                            "Model 3" = c("\\checkmark", "IK"),
                            "Model 4" = c("\\checkmark", "CCT"),
                            "Model 5" = c("\\checkmark", "IK"),
                            "Model 6" = c("\\checkmark", "CCT"),
                            "Model 7" = c("\\checkmark", "IK"),
                            "Model 8" = c("\\checkmark", "CCT"))

attr(tab2_FEs, "position") <- 3:4

tab2 <- modelsummary(list(pois_ind_quart_ik, pois_ind_quart_cct, pois_ind_med_ik, pois_ind_med_cct,
                  pois_corp_quart_ik, pois_corp_quart_cct, pois_corp_med_ik, pois_corp_med_cct),
                              stars = c('*' = 0.05, '**' = 0.01, '***' = 0.001),add_rows=tab2_FEs, 
                              fmt = fmt_r4, gof_map = gm, output = "latex", col.names=NULL, escape = F,
                              coef_map = c("ext_win" = "Extremist Win"),
                              title = "Regression Discontinuity Estimates of Effect of Nominating Extremist on General Election Contributions") %>% 
  kable_styling(font_size = 10) %>% 
  add_header_above(c(" " = 1, "Top 25% Distance" = 2, "Top 50% Distance" = 2, "Top 25% Distance" = 2, "Top 50% Distance" = 2)) %>%
  add_header_above(c(" " = 1, "Individual Contributions" = 4, "Corporate PAC Contributions" = 4)) 

save_kable(tab2, "tab2.tex")

###################################################
# Table 3
###################################################
# Reading in contributor-candidate-dyad data 
indiv_multi <- readRDS("Indiv_Multi.rds") # Individuals who gave to multiple candidates
indiv_over5 <- readRDS("Indiv_Over5.rds") # Individuals who gave to more than 5 candidates
indiv_partisan <- readRDS("Indiv_Partisan.rds") # Individuals who gave to only one party
corp_all <- readRDS("Corp_All.rds") # Corporate PACs

# Binary choice to give
lm_ind_multi <- feols(bin_gave ~ ext_win * ext_vshare | factor(year), indiv_multi, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_over5 <- feols(bin_gave ~ ext_win * ext_vshare | factor(year), indiv_over5, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_partisan <- feols(bin_gave ~ ext_win * ext_vshare | factor(year), indiv_partisan, weights = ~ik.wgt, cluster = "bonica.cid")
lm_corp_all <- feols(bin_gave ~ ext_win * ext_vshare | factor(year), corp_all, weights = ~ik.wgt, cluster = "bonica.cid")

# Build results table
fmt_r3 <- function(x) format(round(x, digits=3), nsmall=3)

ik.bw.indiv_multi <- fmt_r3(IKbandwidth(indiv_multi$ext_vshare, indiv_multi$bin_gave, kernel = "triangular", cutpoint = 0))
ik.bw.indiv_over5 <- fmt_r3(IKbandwidth(indiv_over5$ext_vshare, indiv_over5$bin_gave, kernel = "triangular", cutpoint = 0))
ik.bw.indiv_partisan <- fmt_r3(IKbandwidth(indiv_partisan$ext_vshare, indiv_partisan$bin_gave, kernel = "triangular", cutpoint = 0))
ik.bw.corp_all <- fmt_r3(IKbandwidth(corp_all$ext_vshare, corp_all$bin_gave, kernel = "triangular", cutpoint = 0))

baseline.indiv_multi <- fmt_r4(mean(indiv_multi$bin_gave[indiv_multi$ext_win==0 & indiv_multi$ik.wgt > 0], na.rm=T))
baseline.indiv_over5 <- fmt_r4(mean(indiv_over5$bin_gave[indiv_over5$ext_win==0 & indiv_over5$ik.wgt > 0], na.rm=T))
baseline.indiv_partisan <- fmt_r4(mean(indiv_partisan$bin_gave[indiv_partisan$ext_win==0 & indiv_partisan$ik.wgt > 0], na.rm=T))
baseline.corp_all <- fmt_r4(mean(corp_all$bin_gave[corp_all$ext_win==0 & corp_all$ik.wgt > 0], na.rm=T))

tab3_FEs <- data.frame("Coefficients" = c("Year FE", "Bandwidth", "Baseline"),
                         "Model 1" = c("\\checkmark", ik.bw.indiv_multi, baseline.indiv_multi),
                         "Model 2" = c("\\checkmark", ik.bw.indiv_over5, baseline.indiv_over5),
                         "Model 3" = c("\\checkmark", ik.bw.indiv_partisan, baseline.indiv_partisan),
                         "Model 4" = c("\\checkmark", ik.bw.corp_all, baseline.corp_all))

attr(tab3_FEs, "position") <- 3:5

tab3 <- modelsummary(list("Indivs $>$ 1 Race" = lm_ind_multi, "Indivs $>$ 5 Races" = lm_ind_over5, 
                  "Pure Partisans" = lm_ind_partisan, "Corporate PACs" = lm_corp_all),
             stars = c('*' = 0.05, '**' = 0.01, '***' = 0.001),add_rows=tab3_FEs, 
             fmt = fmt_r4, gof_map = gm, escape = F, output = "latex", coef_map = c("ext_win" = "Extremist Win"),
             title = "Regression Discontinuity Estimates of Effect of Nominating Extremist on Likelihood of General Election Contribution") %>%
  kable_styling(font_size = 10)

save_kable(tab3, "tab3.tex")

###################################################
# Table 4
###################################################
# Adding in district safety interactions
lm_ind_multi_safety <- feols(bin_gave ~ ext_win * ext_vshare * safe | factor(year), indiv_multi, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_over5_safety <- feols(bin_gave ~ ext_win * ext_vshare * safe | factor(year), indiv_over5, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_partisan_safety <- feols(bin_gave ~ ext_win * ext_vshare * safe | factor(year), indiv_partisan, weights = ~ik.wgt, cluster = "bonica.cid")
lm_corp_safety <- feols(bin_gave ~ ext_win * ext_vshare * safe | factor(year), corp_all, weights = ~ik.wgt, cluster = "bonica.cid")

# Adding in race type interactions
lm_ind_multi_racetype <- feols(bin_gave ~ ext_win * ext_vshare * race_type | factor(year), indiv_multi, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_over5_racetype <- feols(bin_gave ~ ext_win * ext_vshare * race_type | factor(year), indiv_over5, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_partisan_racetype <- feols(bin_gave ~ ext_win * ext_vshare * race_type | factor(year), indiv_partisan, weights = ~ik.wgt, cluster = "bonica.cid")
lm_corp_racetype <- feols(bin_gave ~ ext_win * ext_vshare * race_type | factor(year), corp_all, weights = ~ik.wgt, cluster = "bonica.cid")

# Build results table
tab4_FEs <- data.frame("Coefficients" = c("Year FE", "Bandwidth"),
                                         "Model 1" = c("\\checkmark", ik.bw.indiv_multi),
                                         "Model 2" = c("\\checkmark", ik.bw.indiv_over5),
                                         "Model 3" = c("\\checkmark", ik.bw.indiv_partisan),
                                         "Model 4" = c("\\checkmark", ik.bw.corp_all),
                                         "Model 5" = c("\\checkmark", ik.bw.indiv_multi),
                                         "Model 6" = c("\\checkmark", ik.bw.indiv_over5),
                                         "Model 7" = c("\\checkmark", ik.bw.indiv_partisan),
                                         "Model 8" = c("\\checkmark", ik.bw.corp_all))

attr(tab4_FEs, "position") <- 11:12

tab4 <- modelsummary(list(lm_ind_multi_safety, lm_ind_multi_racetype, lm_ind_over5_safety, lm_ind_over5_racetype,
                  lm_ind_partisan_safety, lm_ind_partisan_racetype, lm_corp_safety, lm_corp_racetype),
                                           stars = c('*' = 0.05, '**' = 0.01, '***' = 0.001), add_rows=tab4_FEs, 
                                           fmt = fmt_r4, gof_map = gm, escape = F, output = "latex", col.names=NULL, 
                                           coef_map = c("ext_win" = "Extremist Win",
                                                        "safe" = "Safe District",
                                                        "ext_win:safe" = "Extremist Win x Safe",
                                                        "race_typeO" = "Open Seat",
                                                        "ext_win:race_typeO" = "Extremist Win x Open"),
                                           title = "Regression Discontinuity Estimates of Effect of Nominating Extremist on General Election Contributions") %>%
  kable_styling(font_size = 8) %>% 
  add_header_above(c(" " = 1, "Indivs > 1 Race" = 2, "Indivs > 5 Races" = 2, "Pure Partisans" = 2, "Corporate PACs" = 2))

save_kable(tab4, "tab4.tex")

###################################################
# Table 5
###################################################
# Adding interaction for post-1994
lm_ind_multi_1994cutoff <- feols(bin_gave ~ ext_win * ext_vshare * post1994, indiv_multi, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_over5_1994cutoff <- feols(bin_gave ~ ext_win * ext_vshare * post1994, indiv_over5, weights = ~ik.wgt, cluster = "bonica.cid")
lm_ind_partisan_1994cutoff <- feols(bin_gave ~ ext_win * ext_vshare * post1994, indiv_partisan, weights = ~ik.wgt, cluster = "bonica.cid")
lm_corp_1994cutoff <- feols(bin_gave ~ ext_win * ext_vshare * post1994, corp_all, weights = ~ik.wgt, cluster = "bonica.cid")

# Build results table
tab5_FEs <- data.frame("Coefficients" = c("Bandwidth"),
                              "Model 1" = c(ik.bw.indiv_multi),
                              "Model 2" = c(ik.bw.indiv_over5),
                              "Model 3" = c(ik.bw.indiv_partisan),
                              "Model 4" = c(ik.bw.corp_all))

attr(tab5_FEs, "position") <- 7

tab5 <- modelsummary(list("Indivs $>$ 1 Race" = lm_ind_multi_1994cutoff, "Indivs $>$ 5 Races" = lm_ind_over5_1994cutoff, 
                  "Pure Partisans" = lm_ind_partisan_1994cutoff, "Corporate PACs" = lm_corp_1994cutoff),
                                    stars = c('*' = 0.05, '**' = 0.01, '***' = 0.001),add_rows=tab5_FEs, 
                                    fmt = fmt_r4, gof_map = gm, escape = F, output = "latex", 
                                    coef_map = c("ext_win" = "Extremist Win",
                                                 "post1994" = "Post-1994",
                                                 "ext_win:post1994" = "Extremist Win x Post-1994"),
                                    title = "Regression Discontinuity Estimates of Effect of Nominating Extremist on General Election Contributions") %>%
  kable_styling(font_size = 10)

save_kable(tab5, "tab5.tex")

